package com.mars.pay.service;

import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.kernel.util.ResponseChecker;
import com.alipay.easysdk.payment.page.models.AlipayTradePagePayResponse;
import com.alipay.easysdk.payment.common.models.AlipayTradeQueryResponse;
import com.google.gson.Gson;
import com.mars.pay.common.PaymentStatusEnum;
import com.mars.pay.common.PaymentTypeEnum;
import com.mars.pay.config.AlipayConfig;
import com.mars.pay.entity.Order;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Map;

/**
 * 支付宝支付服务
 *
 * @author Mars
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AlipayService {

    private final AlipayConfig alipayConfig;
    private final OrderService orderService;
    private final PaymentLogService paymentLogService;
    private final Gson gson;

    /**
     * 电脑网站支付
     *
     * @param order 订单信息
     * @return 支付表单
     */
    public String pagePay(Order order) {
        try {
            // 调用支付宝电脑网站支付接口
            AlipayTradePagePayResponse response = Factory.Payment.Page()
                    .pay(order.getProductName(), order.getOrderNo(), 
                         order.getAmount().toString(), alipayConfig.getReturnUrl());
            
            // 获取支付表单
            String form = response.getBody();
            
            // 更新订单状态为支付中
            orderService.updateOrderStatus(order.getOrderNo(), PaymentStatusEnum.PAYING.getCode(), 
                    null, PaymentTypeEnum.ALIPAY.getCode());
            
            // 记录日志
            paymentLogService.recordLog(order.getOrderNo(), null, PaymentTypeEnum.ALIPAY.getCode(),
                    "CREATE", gson.toJson(order), form, 1, "支付宝电脑网站支付下单成功");
            
            log.info("支付宝支付下单成功：订单号={}", order.getOrderNo());
            
            return form;
        } catch (Exception e) {
            log.error("支付宝支付下单失败：订单号={}", order.getOrderNo(), e);
            
            // 记录错误日志
            paymentLogService.recordLog(order.getOrderNo(), null, PaymentTypeEnum.ALIPAY.getCode(),
                    "CREATE", null, e.getMessage(), 0, "支付宝支付下单失败");
            
            throw new RuntimeException("支付宝支付下单失败：" + e.getMessage(), e);
        }
    }

    /**
     * 处理支付宝回调通知
     *
     * @param params 回调参数
     * @return 处理结果
     */
    public boolean handleNotify(Map<String, String> params) {
        try {
            // 验签
            boolean signVerified = Factory.Payment.Common().verifyNotify(params);
            if (!signVerified) {
                log.warn("支付宝回调验签失败：{}", gson.toJson(params));
                return false;
            }
            
            // 获取回调参数
            String outTradeNo = params.get("out_trade_no");
            String tradeNo = params.get("trade_no");
            String tradeStatus = params.get("trade_status");
            
            log.info("收到支付宝回调：订单号={}, 交易号={}, 状态={}", 
                    outTradeNo, tradeNo, tradeStatus);
            
            // 查询订单
            Order order = orderService.getByOrderNo(outTradeNo);
            if (order == null) {
                log.warn("订单不存在：{}", outTradeNo);
                return false;
            }
            
            // 判断订单状态
            if (PaymentStatusEnum.SUCCESS.getCode().equals(order.getStatus())) {
                log.info("订单已支付，无需重复处理：{}", outTradeNo);
                return true;
            }
            
            // 根据支付状态更新订单
            // TRADE_SUCCESS 或 TRADE_FINISHED 表示支付成功
            if ("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus)) {
                orderService.updateOrderStatus(outTradeNo, PaymentStatusEnum.SUCCESS.getCode(), 
                        tradeNo, PaymentTypeEnum.ALIPAY.getCode());
                
                // 记录日志
                paymentLogService.recordLog(outTradeNo, tradeNo, PaymentTypeEnum.ALIPAY.getCode(),
                        "NOTIFY", gson.toJson(params), "SUCCESS", 1, "支付成功");
                
                log.info("订单支付成功：{}", outTradeNo);
                return true;
            } else if ("TRADE_CLOSED".equals(tradeStatus)) {
                // 交易关闭
                orderService.updateOrderStatus(outTradeNo, PaymentStatusEnum.CLOSED.getCode(), 
                        tradeNo, PaymentTypeEnum.ALIPAY.getCode());
                
                // 记录日志
                paymentLogService.recordLog(outTradeNo, tradeNo, PaymentTypeEnum.ALIPAY.getCode(),
                        "NOTIFY", gson.toJson(params), "CLOSED", 0, "交易关闭");
                
                log.warn("订单交易关闭：{}", outTradeNo);
                return true;
            } else {
                log.warn("未处理的支付状态：订单号={}, 状态={}", outTradeNo, tradeStatus);
                return false;
            }
        } catch (Exception e) {
            log.error("处理支付宝回调失败", e);
            
            // 记录错误日志
            paymentLogService.recordLog(null, null, PaymentTypeEnum.ALIPAY.getCode(),
                    "NOTIFY", gson.toJson(params), e.getMessage(), 0, "回调处理异常");
            
            return false;
        }
    }

    /**
     * 查询支付状态
     *
     * @param orderNo 订单号
     * @return 查询结果
     */
    public AlipayTradeQueryResponse queryOrder(String orderNo) {
        try {
            AlipayTradeQueryResponse response = Factory.Payment.Common().query(orderNo);
            
            log.info("查询支付宝支付状态：订单号={}, 状态={}", orderNo, response.getTradeStatus());
            
            // 记录日志
            paymentLogService.recordLog(orderNo, response.getTradeNo(), 
                    PaymentTypeEnum.ALIPAY.getCode(), "QUERY", orderNo, 
                    gson.toJson(response), 1, "查询成功");
            
            return response;
        } catch (Exception e) {
            log.error("查询支付宝支付状态失败：订单号={}", orderNo, e);
            
            // 记录日志
            paymentLogService.recordLog(orderNo, null, PaymentTypeEnum.ALIPAY.getCode(),
                    "QUERY", orderNo, e.getMessage(), 0, "查询失败");
            
            throw new RuntimeException("查询支付状态失败：" + e.getMessage(), e);
        }
    }
}

